home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / ncsat.cpt / Telnet2.5 final / tcpip / userd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-14  |  37.4 KB  |  1,680 lines

  1. /*
  2. *  USER.C
  3. *  Network library interface routines
  4. *  Generally called by the session layer
  5. *
  6. ****************************************************************************
  7. *                                                                          *
  8. *      part of:                                                            *
  9. *      TCP/IP kernel for NCSA Telnet                                       *
  10. *      by Tim Krauskopf                                                    *
  11. *                                                                          *
  12. *      National Center for Supercomputing Applications                     *
  13. *      152 Computing Applications Building                                 *
  14. *      605 E. Springfield Ave.                                             *
  15. *      Champaign, IL  61820                                                *
  16. *                                                                          *
  17. *    Copyright (c) 1987, Board of Trustees of the University of Illinois   *
  18. *                                                                          *
  19. ****************************************************************************
  20. *  Revisions:
  21. *  10/87  Initial source release, Tim Krauskopf
  22. *  2/88  typedef support for other compilers (TK)
  23. *  8/88  Gaige Paulsen - support for MacTCP drivers
  24. *  1/89  TK - conversion to new drivers, minor update for new calling convention
  25. *  6/89  TK - update to MacTCP 1.0 include files and use of GetMyIPAddr()
  26. *
  27. */
  28.  
  29. #include <Dialogs.h>
  30. #include <Devices.h>
  31. #include <Memory.h>
  32. #include <MacTCPCommonTypes.h>
  33. #include <TCPPB.h>
  34. #include <UDPPB.h>
  35.  
  36. /*#define MASTERDEF 1        /* BYU 2.4.16 */
  37. #include <stdio.h>
  38. #include <String.h>
  39. #include "protocol.h"
  40. #include "data.h"
  41. #include "configrec.h"
  42. #include "maclook.h"
  43. #include "menu.h"
  44. #include "tools.h"
  45. #include "user.h"            /* BYU 2.4.16 MPW */
  46. #include <getmyipaddr.h>
  47.  
  48. extern int                     /* BYU 2.4.15 */
  49.     net_okay;                /* BYU 2.4.15 */
  50.  
  51. extern short                /* BYU 2.4.15 */
  52.     slip_connection;        /* BYU 2.4.15 */
  53.  
  54. extern int                     /* BYU 2.4.16 */
  55.     EtherNet;                /* BYU 2.4.16 - Signify Drivers */
  56.  
  57. #define LOWWATER 600
  58.  
  59. pascal void TCPNotify();
  60. pascal void UDPNotify();
  61. long openComplete();
  62. long closeComplete();
  63. long sendComplete();
  64.  
  65. /*
  66.  * UDP Stuff
  67.  */
  68.  
  69. #define    UDPBUFSIZ    (1024*8)
  70. #define    getUPB(x,y,z,a)    (UDPiopb *)getPB(x,y,z,a)
  71.  
  72. typedef struct UDPRec {
  73.     StreamPtr stream;                /* Apple's lovely Stream Pointer */
  74.     char   *buffer;                    /* Where the immovable UDP buffer is */
  75.     uint    port;                    /* Which UDP port to use */
  76.     } UDPRec, *UDPRPtr;
  77.  
  78. UDPRPtr uport[ NPORTS];                /* our wonderful little thingies. */
  79.  
  80. /*
  81.  * TCP Stuff
  82.  */
  83. #define    noError    0
  84. #define TCPBUFSIZ    (1024*8)
  85. #define    MAX_FDS_ELEMS    32
  86. #define    MAX_SWDS_ELEMS    8
  87. #define MAX_FREE_PB        128
  88. #define MAX_FREE_SWDS    64
  89.  
  90. /* NCSA 2.5 */
  91. #define    MAX_BEFORE_RECYCLE  (MAX_FREE_PB - 5)
  92.  
  93. #define    Qcall    true
  94. #define    noQcall    false
  95.  
  96. returnPB(TCPiopb *);
  97.  
  98. #define UNKNOWN_PORT_TYPE    0        /* BYU 2.4.16 */
  99. #define MACTCP_PORT_TYPE    1        /* BYU 2.4.16 */
  100. #define NCSA_PORT_TYPE        2        /* BYU 2.4.16 */
  101.  
  102. extern short porttype[];                /* BYU 2.4.16 */
  103.  
  104.  
  105. typedef    struct freeEntry {
  106.     int inuse;                        /* is this being used? */
  107.     Ptr    ptr;                        /* Pointer to the free entry */
  108.     } freeEntry;
  109.     
  110. typedef struct exfds {
  111.     int    inuse;                        /* Is this being used */
  112.     wdsEntry fds;                    /* The real data */
  113.     } exfds;
  114.     
  115. typedef struct StreamRec {
  116.     StreamPtr stream;                /* Apple's lovely Stream Pointer */
  117.     char   *buffer;                    /* Where the immovable TCP buffer is */
  118.     int        push;                    /* TRUE if we should push next data block */
  119.     char   *sbuffer;                /* Where the send buffer is */
  120.     wdsEntry    fds[MAX_FDS_ELEMS];    /* Free Data Structure list */
  121.     exfds    exFDS[MAX_FDS_ELEMS];    /* exFDS entries */
  122.     int        maxFDSused;                /* Max of the FDS's that have been used */
  123.     int        mseg;                    /* BYU 2.4.15 */
  124.     int        service;                /* BYU 2.4.15 */
  125.     int        type;                    /* BYU 2.4.15 - 0 = non-serial, 1 = serial or SLIP */
  126.     } StreamRec, *StreamRPtr;
  127.     
  128. short TCPd = 0;                        /* refnum of TCP drivers */
  129.  
  130. StreamRPtr streams[NPORTS];
  131.  
  132. int numPB=0;                        /* Number of PB's ever allocated  (Perf. mon. only ) */
  133. int numSWDS=0;                        /* Number of SWDS's ever alloc'd (PM Only) */
  134.  
  135. freeEntry    freePB[ MAX_FREE_PB];
  136. freeEntry    freeSWDS[ MAX_FREE_SWDS];
  137.  
  138. /**************************************************************************/
  139. wdsEntry *getSWDS
  140.   (
  141.     void
  142.   )
  143. {
  144.     int n=0;
  145.     
  146.     while (freeSWDS[n].inuse &&  n<MAX_FREE_SWDS) n++;
  147.     if (n >= MAX_FREE_SWDS)
  148.         return((wdsEntry *) 0L);
  149.     
  150.     freeSWDS[n].inuse=1;
  151.     if (freeSWDS[n].ptr==0L) {
  152.  
  153.         freeSWDS[n].ptr = NewPtr ( sizeof(wdsEntry) *MAX_SWDS_ELEMS);
  154.         numSWDS++;
  155. /*        sprintf(temp,"New SWDS(%d)",numSWDS);
  156.         putln(temp); */
  157.         }
  158.     return((wdsEntry *) freeSWDS[n].ptr);
  159. }
  160.  
  161. /**************************************************************************/
  162. returnSWDS( wds)
  163. wdsEntry *wds;
  164. {
  165.     int n=0;
  166.     
  167.     while (freeSWDS[n].ptr != wds && n<MAX_FREE_SWDS) n++;
  168.     if (n >= MAX_FREE_SWDS)
  169.         return(-1);
  170.     freeSWDS[n].inuse=0;
  171. }
  172.  
  173.  
  174. /**************************************************************************/
  175. TCPiopb *getPB( driver, call, stream, usernum)
  176. int driver, call, usernum;
  177. unsigned long stream;
  178. {
  179. #pragma unused(usernum)
  180.     TCPiopb *pbp;
  181.     int n=0;
  182.     int i;
  183.     
  184.     while (freePB[n].inuse &&  n<MAX_FREE_PB) n++;
  185.  
  186.  
  187.     if (n >= 100)    /* recycle memory so system doesn't get hammered */
  188.         {
  189.         for (i = 0;i < MAX_BEFORE_RECYCLE;i++)        /* NCSA 2.5 */
  190.             {
  191.             if ((freePB[i].inuse) && !(((TCPiopb *)(freePB[i].ptr))->ioResult) )
  192.                 {
  193.                 returnPB((TCPiopb *)freePB[i].ptr); /* re-use this one */
  194.                 n--;                     /* so there is now one less */
  195.                 }
  196.             }
  197.         }
  198.         
  199.     if (n >= MAX_FREE_PB) return(0L);    /* hammer system */
  200.     
  201.     freePB[n].inuse = 1;                
  202.     if (freePB[n].ptr==0L) {
  203.         
  204.         freePB[n].ptr = NewPtr ( sizeof(TCPiopb)+sizeof(int) );
  205.         numPB++;
  206. /*        sprintf(temp,"New PB(%d)",numPB);
  207.         putln(temp); */
  208.         }
  209.     (Ptr) pbp = freePB[n].ptr;
  210.  
  211.  
  212.     if (!pbp) {
  213.         putln("GETPB failed! panic! ");
  214.         quit();
  215.         }
  216.     
  217.     memset( pbp, '\0', sizeof(TCPiopb)+sizeof(int));    /* Default to all zeros */
  218.     
  219.     pbp->ioCRefNum = driver;
  220.     pbp->tcpStream=stream;
  221.     pbp->csCode = call;
  222.     
  223.     return(pbp);
  224. }
  225.  
  226. /**************************************************************************/
  227. clearPB( pbp, driver, call, stream, usernum)
  228. TCPiopb *pbp;
  229. int driver, call, usernum;
  230. unsigned long stream;
  231. {
  232. #pragma unused(usernum)
  233.     memset( pbp, '\0', sizeof(TCPiopb)+sizeof(int));    /* Default to all zeros */
  234.     
  235.     pbp->ioCRefNum = driver;
  236.     pbp->tcpStream=stream;
  237.     pbp->csCode = call;
  238.     
  239. }
  240.  
  241. returnPB( pbp)
  242. TCPiopb *pbp;
  243. {
  244.     int n=0;
  245.     
  246.     while (freePB[n].ptr != pbp && n<MAX_FREE_PB) n++;
  247.     if (n >= MAX_FREE_PB)
  248.         return(-1);
  249.     freePB[n].inuse=0;
  250.     
  251. }
  252.  
  253. /***************************************************************************/
  254. /*  Mnetread
  255. *   Read from a connection buffer into a user buffer.  
  256. *   Returns number of bytes read, < 0 on error
  257. * NOTE:
  258. *    current version very inefficient, but hopefully works.
  259. */
  260. Mnetread(pnum,buffer,n)                        /* BYU 2.4.16 */
  261.     int pnum,n;
  262.     char *buffer;
  263.     {
  264.     int i;
  265.     StreamRPtr p;
  266.     TCPiopb *pbp;
  267.     int inQ, reqdamt;
  268.  
  269.     if (pnum < 0 || pnum >= NPORTS)            /* BYU 2.4.15 */
  270.         return(-2);
  271.  
  272.     if (NULL == (p = streams[pnum]))
  273.         return(-2);
  274.     
  275.     
  276.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  277.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  278.         putln("TCPStatus failed(read)"); return(-1);
  279.         }
  280. #ifdef DEBUGHEADERS    
  281.     { char temp[100];
  282.         sprintf(temp, "Stat: %x(%d)->%x(%d) <%d,%d,%d> [%d,%d] {%d,%d}",
  283.             (int)pbp->csParam.status.remoteHost,
  284.             (int)pbp->csParam.status.remotePort,
  285.             (int)pbp->csParam.status.localHost,
  286.             (int)pbp->csParam.status.localPort,
  287.             (int)pbp->csParam.status.tosFlags,
  288.             (int)pbp->csParam.status.precedence,
  289.             (int)pbp->csParam.status.connectionState,
  290.             (int)pbp->csParam.status.sendWindow,
  291.             (int)pbp->csParam.status.rcvWindow,
  292.             (int)pbp->csParam.status.amtUnackedData,
  293.             (int)pbp->csParam.status.amtUnreadData);
  294.         putln(temp);
  295.     }
  296. #endif DEBUGHEADERS
  297.     
  298.     if (pbp->csParam.status.connectionState !=8) {
  299.         char temp[50];
  300.         sprintf(temp,"CState: %d is %d",(int)pnum, (int)pbp->csParam.status.connectionState);
  301.         putln(temp);
  302.         return(-1);                              /* Connection not established */
  303.         }
  304.     
  305.     inQ = pbp->csParam.status.amtUnreadData;
  306.     reqdamt = n >inQ ? inQ : n;
  307.     
  308.     clearPB( pbp, TCPd, TCPRcv, p->stream, pnum);
  309.     pbp->csParam.receive.rcvBuff = buffer;
  310.     pbp->csParam.receive.rcvBuffLen = reqdamt;
  311.     
  312.     if (reqdamt<1) {                                /* Drop out if no data */
  313.         returnPB(pbp);
  314.         return(0);
  315.         }
  316.     
  317.     if ((i = PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
  318.         char temp[100];
  319.         sprintf(temp,"TCPRcv failed (%d)",i);
  320.         putln( temp);
  321.         return(-1);
  322.         }
  323.         
  324.     reqdamt = pbp->csParam.receive.rcvBuffLen;
  325.     if (reqdamt<inQ) {
  326.         netputuev( CONCLASS, CONDATA, pnum);            /* more data to get */
  327.         }
  328.         
  329.     returnPB(pbp);                    /* Trash PB */
  330. #ifdef TESTINGPARMS
  331.     {
  332.         char temp[100];
  333.         sprintf(temp, "NETRead: %d from %d", reqdamt, pnum);
  334.         putln(temp);
  335.     }
  336. #endif TESTINGPARMS
  337.     return(reqdamt);
  338. }
  339.  
  340. /**************************************************************************/
  341. /* 
  342.  *    reclaim( p) -
  343.  *        reclaims buffer space to stream (from pointer p) into the FDS list 
  344.  */
  345.  
  346. reclaim(p)
  347. StreamRPtr p;
  348. {
  349.     int n=0, offset=0;
  350.     
  351.     while (offset < MAX_FDS_ELEMS && p->fds[offset].ptr != 0L) offset++;
  352.     
  353.     if (offset >= MAX_FDS_ELEMS) {
  354.         putln("Couldn't reclaim because offset was too large ");
  355.         return(0);
  356.         }
  357.     for (n=0 ; n<MAX_FDS_ELEMS && offset< MAX_FDS_ELEMS; n++) {
  358.         if (p->exFDS[ n].inuse) {
  359.             p->fds[ offset++]=p->exFDS[ n].fds;
  360.             p->exFDS[ n].inuse = 0;
  361.             }
  362.         }
  363. }
  364.  
  365. /**************************************************************************/
  366. /*
  367.  *     compressfds( fds)
  368.  *        compress an fds data structure to make everyone happy
  369.  */
  370.  
  371. compressfds( fds)
  372. wdsEntry *fds;
  373. {
  374.     int n,m,compressed;
  375.     
  376.     compressed = 0;
  377.     
  378.     while ( !compressed) {
  379.         compressed=1;
  380.         for (n=0; n< MAX_FDS_ELEMS; n++) {                /* Slow Forwards */
  381.             if (fds[n].ptr) {                                /* Do if N exists */
  382.                 for ( m = MAX_FDS_ELEMS -1; m>=0; m--) {    /* Fast Backwards */
  383.                     if (fds[m].ptr && (fds[m].ptr+fds[m].length == fds[n].ptr)) {
  384.                         fds[n].length+=fds[m].length;
  385.                         fds[n].ptr = fds[m].ptr;
  386.                         fds[m].ptr=0L;
  387.                         fds[m].length=0;
  388.                         compressed=0;
  389.                         }
  390. #ifdef CHECKBOTHWAYZ
  391.                     else 
  392.                     if (fds[n].ptr+fds[n].length == fds[m].ptr) {
  393.                         fds[m].length+=fds[n].length;
  394.                         fds[n].ptr=0L;
  395.                         fds[n].length=0;
  396.                         compressed=0;
  397.                         }
  398. #endif CHECKBOTHWAYZ
  399.                     }
  400.                 }
  401.             }
  402.         }
  403.     m=0;n=0;
  404.     
  405.     /* Close the gaps */
  406.     
  407.     while (n+m < MAX_FDS_ELEMS) {
  408.         while (fds[n+m].ptr ==0L && n+m< MAX_FDS_ELEMS) {
  409.             m++;            /* increase gap to valid entry */
  410.             }
  411.         if (n+m<MAX_FDS_ELEMS)
  412.             fds[n]=fds[n+m];
  413.         n++;
  414.         }
  415.     
  416.     /* Get rid of the empty spaces */
  417.     
  418.     n--;        /* for the next loop */
  419.     while (n < MAX_FDS_ELEMS) {
  420.         fds[n].ptr=0; fds[n++].length=0;
  421.         }
  422. }
  423.  
  424. /************************************************************************/
  425. /* Mnetwrite
  426. *  write something into the output queue, netsleep routine will come
  427. *  around and send the data, etc.
  428. *
  429. */
  430. int                                        /* BYU 2.4.16 */
  431. Mnetwrite(pnum,buffer,nsend)            /* BYU 2.4.16 */
  432.     int pnum,nsend;
  433.     char *buffer;
  434.     {
  435.     StreamRPtr p;
  436.     wdsEntry *swds;
  437.     int remaining, queued, n,m;
  438.     TCPiopb *pbp;
  439.     
  440.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  441.         return(-2);
  442.  
  443.     if ( (p = streams[pnum]) == NULL)
  444.         return(-2);
  445.     
  446.     if ( !nsend )
  447.         return(0);
  448.         
  449.     swds = getSWDS();
  450.     
  451.     reclaim( p);
  452.     compressfds( p->fds);
  453.  
  454.     n=0; remaining = nsend;
  455.     while (p->fds[n].ptr !=0 && remaining>0 ) {
  456.         swds[n].ptr = p->fds[n].ptr;
  457.         if ( p->fds[n].length > remaining) {
  458.             swds[n].length = remaining;
  459.             p->fds[n].length -= remaining;
  460.             p->fds[n].ptr += remaining;
  461.             remaining=0;
  462.             }
  463.         else {
  464.             swds[n].length =  p->fds[n].length;
  465.             remaining -= p->fds[n].length;
  466.             p->fds[n].length = 0;
  467.             p->fds[n].ptr = 0;
  468.             }
  469.         n++;
  470.         }
  471.     if (n>p->maxFDSused) p->maxFDSused=n;
  472.     
  473.     compressfds( p->fds);
  474.     queued = nsend-remaining;
  475.     
  476.     for (m=0; m<n; m++) {
  477.         memcpy( swds[m].ptr, buffer, swds[m].length);    /* Put data in WDS */
  478.         buffer +=swds[m].length;
  479.         }
  480.     swds[m].ptr =0L;
  481.     swds[m].length=0;
  482.     
  483.     pbp=getPB( TCPd, TCPSend, p->stream, pnum);            /* Make send call */
  484.     pbp->csParam.send.wdsPtr = (Ptr) swds;
  485.     pbp->csParam.send.pushFlag = p->push;
  486.     
  487.     pbp->ioCompletion = (TCPIOCompletionProc) sendComplete;                    /* Completion routine */
  488.  
  489.     p->push=0;
  490.  
  491.     if (PBControl((ParmBlkPtr) pbp, Qcall) != noError) {
  492.         putln("TCPSend failed to Q"); return(-1);
  493.         }
  494.     
  495. #ifdef TESTINGPARMS
  496.     putln("TCP Sent");
  497.     { char temp[100];
  498.         sprintf(temp, "TCP Sent: %d of %d on %d [%d/%d]", queued, nsend, pnum,n,p->maxFDSused);
  499.         putln(temp);
  500.     }
  501. #endif TESTINGPARMS
  502.     return(queued);
  503. }
  504.  
  505. /**************************************************************************/
  506. /*  Mnetpush
  507. *   attempt to push the rest of the data from the queue
  508. *   and then return whether the queue is empty or not (0 = empty)
  509. *   returns the number of bytes in the queue.
  510. */
  511. Mnetpush(pnum)                            /* BYU 2.4.16 */
  512.     int pnum;
  513.     {
  514.     StreamRPtr p;
  515.     TCPiopb *pbp;
  516.     int inQ;
  517.     
  518.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  519.         return(-2);
  520.  
  521.     if (NULL == (p = streams[pnum]))
  522.         return(-2);
  523.  
  524.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  525.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  526.         putln("TCPStatus failed(push)"); return(-1);
  527.         }
  528.     inQ = pbp->csParam.status.amtUnackedData;
  529.     returnPB( pbp);
  530.     
  531.     p->push=1;
  532.     
  533.     return(inQ);
  534.  
  535. }    
  536.  
  537. /**************************************************************************/
  538. /*  Mnetqlen
  539. *   return the number of bytes waiting to be read from the incoming queue.
  540. */
  541. Mnetqlen(pnum)                            /* BYU 2.4.16 */
  542.     int pnum;
  543.     {
  544.     StreamRPtr p;
  545.     TCPiopb *pbp;
  546.     int inQ;
  547.     
  548.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  549.         return(-2);
  550.  
  551.     if (NULL == (p = streams[pnum]))
  552.         return(-2);
  553.  
  554.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  555.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  556.         putln("TCPStatus failed(qlen)"); return(-1);
  557.         }
  558.     inQ = pbp->csParam.status.amtUnreadData;
  559.     returnPB( pbp);
  560.     
  561.     p->push = 1;
  562.     return(inQ);
  563. }
  564.  
  565. /**************************************************************************/
  566. /*  Mnetroom()
  567. *    return how much room is available in output buffer for a connection
  568. */
  569. Mnetroom(pnum)                            /* BYU 2.4.16 */
  570.     int pnum;
  571.     {
  572.     StreamRPtr p;
  573.     TCPiopb *pbp;
  574.     int inQ,n;
  575.     
  576.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  577.         return(-2);
  578.  
  579.     if (NULL == (p = streams[pnum]))
  580.         return(-2);
  581.  
  582.     reclaim( p);
  583.     compressfds( p->fds);
  584.  
  585. #ifdef OLDM
  586.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  587.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  588.         putln("TCPStatus failed(room)"); return(-1);
  589.         }
  590.     inQ = pbp->csParam.status.sendWindow -
  591.                 pbp->csParam.status.amtUnackedData;
  592.     returnPB( pbp);
  593. #else
  594. #pragma unused(pbp)
  595. #endif
  596.  
  597.     inQ = n = 0;
  598.     while (p->fds[n].ptr) {
  599.     
  600.         inQ += p->fds[n].length;                /* add up free list space */
  601.         n++;
  602.         }
  603.  
  604.     return(inQ);
  605. }
  606.  
  607. #if 0                                            /* BYU 2.4.16 */
  608. /**************************************************************************/
  609. /* netsegsize and neterrchange and netsetip and netgetip
  610. *
  611. *  set operating parameters to change them from the default values used.
  612. */
  613.  
  614. netsegsize(newsize)
  615.     int newsize;
  616.     {
  617.     int i;
  618.  
  619.     i = nnsegsize;
  620.     nnsegsize = newsize;
  621.  
  622.     return(i);
  623. }
  624.  
  625. /**************************************************************************/
  626. netquench(newcredit)
  627.     int newcredit;
  628.     {
  629.     int i;
  630.  
  631.     i = nncredit;
  632.     nncredit = newcredit;
  633.  
  634.     return(i);
  635. }
  636.  
  637. /**************************************************************************/
  638. netarptime(t)                    /* dlayer timeout in secs */
  639.     int t;
  640.     {
  641.     nndto = t;
  642. }
  643.  
  644. /**************************************************************************/
  645. void netsetip
  646.   (
  647.     unsigned char *st
  648.   )
  649.     {
  650. /*
  651. *  this is a no-op with the MacTCP driver
  652. */
  653. #pragma unused(st)
  654. }
  655. #endif                                            /* BYU 2.4.16 */
  656.  
  657. /**************************************************************************/
  658. int Mnetgetip                                    /* BYU 2.4.16 */
  659.   (
  660.     unsigned char *st
  661.   )
  662. {
  663.     struct IPParamBlock mypb;
  664.     /* long netmask; */
  665.  
  666.     putln("Attempting getmyipaddr");
  667.     
  668.     memset( &mypb, '\0', sizeof(struct IPParamBlock));    /* Default to all zeros */
  669.     
  670.     mypb.ioCRefNum = TCPd;            /* TCP driver has to be open by now */
  671.     mypb.csCode = ipctlGetAddr;
  672.  
  673.     if (PBControl((ParmBlkPtr) &mypb, noQcall) != noError) {
  674.         putln("Getting my address failed"); 
  675.         return(-1);
  676.         }
  677.     
  678.     memcpy(st, &mypb.ourAddress, 4);    /* copy the address */
  679.     
  680.     /* netmask is here if we want it, too */
  681.     
  682.     return(0);
  683.  
  684. }
  685.  
  686.  
  687. #if 0                                    /* BYU 2.4.16 */
  688. /**************************************************************************/
  689. netsetmask(st)
  690. unsigned char *st;
  691. {
  692.     movebytes(nnmask,st,4);
  693. }
  694.  
  695. /**************************************************************************/
  696. netgetmask(st)
  697. unsigned char *st;
  698. {
  699.     movebytes(st,nnmask,4);
  700. }
  701.  
  702. netfromport(port)            /* next "open" will use this port */
  703. int16 port;
  704. {
  705.     nnfromport = port;
  706.  
  707. }
  708. #endif                                    /* BYU 2.4.16 */
  709.  
  710. /**************************************************************************/
  711. /*  Mnetest?
  712. *  is a particular session established yet?
  713. *  Returns 0 if the connection is in the established state.
  714. */
  715. int                                        /* BYU 2.4.16 */
  716. Mnetest(pnum)                            /* BYU 2.4.16 */
  717. int pnum;
  718. {
  719.     StreamRPtr p;
  720.     TCPiopb *pbp;
  721.     int inQ;
  722.     
  723.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  724.         return(-2);
  725.  
  726.     if (NULL == (p = streams[pnum]))
  727.         return(-2);
  728.  
  729.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  730.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  731.         putln("TCPStatus failed(est)");
  732.         inQ = -1;
  733.         }
  734.     else 
  735.         inQ = pbp->csParam.status.connectionState !=8;
  736.     returnPB( pbp);
  737.     
  738.     return(inQ);
  739.  
  740. }
  741.  
  742. /**************************************************************************/
  743. /*
  744.  * Returns an empty stream
  745.  */ 
  746. int makestream()                /* BYU 2.4.15 */
  747. {
  748.     int    pnum;
  749.     StreamRPtr p;
  750.     TCPiopb *pbp;
  751.     int i;
  752.     
  753.  
  754.     for ( pnum=0; (streams[pnum]!= NULL || porttype[pnum]) && pnum<NPORTS; pnum++);    /* BYU 2.4.16 */
  755.     
  756.     if (pnum >= NPORTS)
  757.         return(-2);
  758.  
  759.     p = streams[pnum] = (StreamRPtr) NewPtr(sizeof(StreamRec));
  760.  
  761.     if ((p->buffer = (char *) NewPtr( TCPBUFSIZ)) == (char *)NULL)
  762.         return(-1);
  763.     if ((p->sbuffer = (char *) NewPtr( TCPBUFSIZ)) == (char *)NULL)
  764.         return(-1);
  765.     
  766.     for (i=0; i<MAX_FDS_ELEMS; i++) {
  767.         p->fds[ i].length =0; p->fds[ i].ptr = 0L;
  768.         p->exFDS[ i].inuse=0; p->exFDS[ i].fds.length=0;p->exFDS[ i].fds.ptr=0L;
  769.         }
  770.     p->fds[0].length = TCPBUFSIZ;
  771.     p->fds[0].ptr = p->sbuffer;
  772.     p->maxFDSused=0;
  773.     
  774.     pbp=getPB( TCPd, TCPCreate, 0, pnum);            /* Make create call */
  775.     pbp->csParam.create.rcvBuff = p->buffer;
  776.     pbp->csParam.create.rcvBuffLen = TCPBUFSIZ;
  777.     pbp->csParam.create.notifyProc = TCPNotify;
  778.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  779.         putln("TCPCreate failed"); return(-1);
  780.         }
  781.     
  782.     p->stream = pbp->tcpStream;
  783.     
  784.     putln("Made a new stream");
  785.     returnPB(pbp);
  786.     return(pnum);
  787. }
  788.  
  789. /**************************************************************************/
  790. /*  Mnetlisten
  791. *   Listen to a TCP port number and make the connection automatically when
  792. *   the SYN packet comes in.  The TCP layer will notify the higher layers
  793. *   with a CONOPEN event.  Save the port number returned to refer to this
  794. *   connection.
  795. *
  796. *   usage:   portnum = netlisten(service);
  797. *            int service;
  798. *
  799. */
  800. int                                        /* BYU 2.4.16 */
  801. Mnetlisten(serv)                        /* BYU 2.4.16 */
  802. uint serv;
  803. {
  804.     int    pnum;
  805.     StreamRPtr p;
  806.     TCPiopb *pbp;
  807.  
  808.     if (!net_okay)                         /* BYU 2.4.15 */
  809.         return(-2);                        /* BYU 2.4.15 */
  810.  
  811.     pnum = makestream();
  812.  
  813.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  814.         return(-2);
  815.  
  816.     if (NULL == (p = streams[pnum]))
  817.         return(-2);
  818.  
  819.     pbp=getPB( TCPd, TCPPassiveOpen, p->stream, pnum);            /* Make Listen call */
  820.     
  821.     pbp->csParam.open.localPort = serv;
  822.     pbp->ioCompletion = (TCPIOCompletionProc) openComplete;        /* IO Completion for open */
  823.     
  824.     if (PBControl((ParmBlkPtr) pbp, Qcall) != noError) {
  825.         putln("TCPListen failed"); return(-1);
  826.         }
  827.         
  828.     return(pnum);
  829. }
  830.  
  831. /***********************************************************************/
  832. /*  Mnetgetftp
  833. *  Provides the information that ftp needs to open a stream back to the
  834. *  originator of the command connection.  The other side's IP number
  835. *  and the port numbers to be used to calculate the default data connection
  836. *  number.  Returns values in an integer array for convenient use in 
  837. *  PORT commands.
  838. */
  839. Mnetgetftp(a,pnum)                                            /* BYU 2.4.16 */
  840. int a[];
  841. int pnum;
  842. {
  843.     StreamRPtr p;
  844.     TCPiopb *pbp;
  845.     long temp;
  846.     
  847.     if (pnum < 0)
  848.         return(-2);
  849.  
  850.     if (NULL == (p = streams[pnum]))
  851.         return(-2);
  852.  
  853.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  854.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  855.         putln("TCPStatus failed(getftp)"); return(-1);
  856.         }
  857.  
  858.     temp      = pbp->csParam.status.remoteHost;
  859.     a[0]= (temp>>24) & 0xff;
  860.     a[1]= (temp>>16) & 0xff;
  861.     a[2]= (temp>> 8) & 0xff;
  862.     a[3]= (temp    ) & 0xff;
  863.     temp    = pbp->csParam.status.localPort;
  864.     a[4]= (temp>> 8) & 0xff;
  865.     a[5]= (temp    ) & 0xff;
  866.     temp    = pbp->csParam.status.remotePort;
  867.     a[6]= (temp>> 8) & 0xff;
  868.     a[7]= (temp    ) & 0xff;
  869.  
  870.     returnPB( pbp);
  871. }
  872.  
  873.  
  874. /**************************************************************************/
  875. /*  Mnetxopen
  876. *   Open a network socket for the user.
  877. *
  878. */
  879. int Mnetxopen                                /* BYU 2.4.16 */
  880.   (
  881.     uint32 *machine,
  882.     uint service,
  883.     uint rto,
  884.     uint mtu,
  885.     uint mseg,
  886.     uint mwin
  887.   )
  888. {
  889. #pragma unused(rto, mtu, mseg, mwin)
  890.     int    pnum;
  891.     StreamRPtr p;
  892.     TCPiopb *pbp;
  893.     char temp[100];
  894.     
  895.     pnum = makestream();
  896.  
  897.     if (pnum < 0)
  898.         return(-2);
  899.  
  900.     if (NULL == (p = streams[pnum]))
  901.         return(-2);
  902.  
  903.     pbp=getPB( TCPd, TCPActiveOpen, p->stream, pnum);            /* Make Listen call */
  904.     
  905.     pbp->csParam.open.remoteHost = *machine;            /* IP # */
  906.     pbp->csParam.open.remotePort = service;                /* Port */
  907.     pbp->csParam.open.localPort = nnfromport;            /* My Port */
  908.     nnfromport=0;                                            /* Next one is random */
  909.     
  910.     pbp->ioCompletion = (TCPIOCompletionProc) openComplete;    /* IO Completion for open */
  911.     
  912.     if (PBControl((ParmBlkPtr) pbp, Qcall) != noError) {
  913.         putln("TCPOpen failed(Active)"); return(-1);
  914.         }
  915.     sprintf(temp,"TCPOpen on %d",pnum);
  916.     putln(temp);
  917.     return(pnum);
  918. }
  919.  
  920. #if 0                                /* BYU 2.4.15 - not used */
  921. /**************************************************************************/
  922. /*  netopen
  923. *   Netopen is a cheap way to open a connection without looking up any
  924. *   machine information.  Uses suitable default values for everything.
  925. */
  926. netopen(s,tport)
  927. unsigned char *s;
  928. uint tport;
  929. {
  930.  
  931.     return(netxopen((uint32 *) s,tport,MINRTO,TSENDSIZE,DEFSEG,DEFWINDOW));
  932. }
  933. #endif
  934.  
  935.  
  936. /**************************************************************************/
  937. /* Mnetclose
  938. *  Do appropriate actions to return connection state to SCLOSED which
  939. *  enables the memory for that port to be reused.
  940. *
  941. *    Specifically:
  942. *        o If status is closed, then release the data structures
  943. *        o If status is not close, perform bkgrd close which generates CLOSEDONE,
  944. *            which should make the session layer call us again
  945. */
  946. int Mnetclose                                /* BYU 2.4.16 */
  947.   (
  948.     int pnum
  949.   )
  950. {
  951.     StreamRPtr p;
  952.     TCPiopb *pbp;
  953.     int errorCode=0;
  954.     int status;
  955.     char temp[50];
  956.     static short count=0;
  957.     
  958.     if (pnum < 0 || pnum > NPORTS)            /* is a valid port? */
  959.         return(-1);
  960.  
  961.     if ((p = streams[pnum]) == NULL)             /* nothing there */
  962.         return (1);
  963.  
  964.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  965.     if ((errorCode = PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
  966.         if ( errorCode == invalidStreamPtr) {
  967.             putln("TCPStatus failed because of bad stream pointer (close)");
  968.             return(-1);
  969.             }
  970.         else
  971.             {
  972.             status=0;
  973.             count =0;
  974.             }
  975.         }
  976.     else 
  977.         {
  978.         status = pbp->csParam.status.connectionState;            /* The connection Status */
  979.         if (count++ ==10) status=count =0;
  980.         }
  981.  
  982. /* */
  983.  
  984.     sprintf(temp,"the error Code is %i",(int)errorCode);
  985.     putln(temp);
  986.  
  987.     if (status < 18 && status >2 ) {                            /* We aren't closed yet ! */
  988.         char temp[50];
  989.         sprintf(temp, "TCPClose being attempted state ...[%d]",status);    /* Prolly because outstanding close */
  990.         putln(temp);
  991.         clearPB( pbp, TCPd, TCPClose, p->stream, pnum);            /* Make Close call */
  992.         pbp->ioCompletion = (TCPIOCompletionProc) closeComplete; /* IO Completion for close */
  993.         if ((errorCode=PBControl((ParmBlkPtr) pbp, Qcall)) != noError) {
  994.             char temp[50];
  995.             sprintf(temp, "TCPClose failed...[%d]",errorCode);    /* Prolly because outstanding close */
  996.             putln(temp);
  997.             putln("we have an error");
  998.             return (errorCode); /* */
  999.             }
  1000.  
  1001.         return (0);                                            /* Return with OK */
  1002.         }
  1003.  
  1004.     /* IF we got here, we must be at closed state, so free memory */
  1005.  
  1006.     putln("TCP Being Released...... ");
  1007.     clearPB( pbp,TCPd, TCPRelease, p->stream, pnum);            /* Make Release call */
  1008.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1009.         putln("TCPRelease failed"); return(-1);
  1010.         }
  1011.     
  1012.     DisposPtr( p->buffer);                /* Free Receive Buffer */
  1013.     DisposPtr( p->sbuffer);                /* Free Send Buffer */
  1014.     DisposPtr((Ptr) p);                    /* Free Stream Structure */
  1015.     streams[pnum]=0L;
  1016.     porttype[pnum] = UNKNOWN_PORT_TYPE;    /* BYU 2.4.16 */
  1017.  
  1018.     returnPB(pbp);
  1019.     return(0);
  1020. }
  1021.  
  1022. /**************************************************************************/
  1023. /* netabort
  1024. *    Nuke the connection, NOW!
  1025. */
  1026. netabort(pnum)
  1027. int pnum;
  1028. {
  1029.     StreamRPtr p;
  1030.     TCPiopb *pbp;
  1031.     int errorCode=0;
  1032.  
  1033.     if (pnum < 0 || pnum > NPORTS)            /* is a valid port? */
  1034.         return(-1);
  1035.  
  1036.     if ((p = streams[pnum]) != NULL) {            /* something there */
  1037.         pbp=getPB( TCPd, TCPAbort, p->stream, pnum);            /* Make Close call */
  1038.         if ((errorCode=PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
  1039.             char temp[50];
  1040.             sprintf(temp, "TCPAbort failed...[%d]",errorCode);
  1041.             putln(temp);
  1042.             }
  1043.         clearPB( pbp,TCPd, TCPRelease, p->stream, pnum);            /* Make Close call */
  1044.         if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1045.             putln("TCPRelease failed"); return(-1);
  1046.             }
  1047.         }
  1048.     else
  1049.         return(1);
  1050.     
  1051.     DisposPtr( p->buffer);                /* Free Receive Buffer */
  1052.     DisposPtr( p->sbuffer);                /* Free Send Buffer */
  1053.     DisposPtr((Ptr) p);                    /* Free Stream Structure */
  1054.     streams[pnum]=0L;
  1055.     porttype[pnum] = UNKNOWN_PORT_TYPE;    /* BYU 2.4.16 */
  1056.  
  1057.     returnPB(pbp);
  1058.     return(0);
  1059. }
  1060.  
  1061. /**************************************************************************/
  1062. /*  Mnetinit
  1063. *   Calls all of the various initialization routines that set up queueing
  1064. *   variables, static values, reads configuration files, etc.
  1065. */
  1066.  
  1067. int Mnetinit                                        /* BYU 2.4.16 */
  1068.   (
  1069.     void
  1070.   )
  1071. {
  1072.     int i;
  1073. extern Cursor *normcurs;
  1074.     
  1075.     for (i=0; i<NPORTS;i++)
  1076.         streams[i]= (StreamRPtr) 0;
  1077.         
  1078.     for (i=0; i<NPORTS;i++)
  1079.         uport[i]= (UDPRPtr) 0;
  1080.     
  1081.     if (opendriver(".IPP",&TCPd) != noError) {
  1082.         SetCursor(normcurs);
  1083.         putln( "Couldn't open IP driver ");
  1084.         OtherError("Error opening TCP drivers.","Possibly no dynamic addressing");
  1085.         EtherNet = -100;    /* BYU 2.4.16 - show serial connections only */
  1086. /*        quit();                /* BYU 2.4.16 */
  1087.         }
  1088.         
  1089.     return(0);                /* set up empty packets */
  1090. }
  1091.  
  1092. /**************************************************************************/
  1093. int UDPfindport( port)
  1094. int port;
  1095. {
  1096.     int pnum=0;
  1097.     
  1098.     while (pnum<NPORTS &&
  1099.             ( uport[pnum] ==(UDPRPtr)0L || port !=uport[pnum]->port))
  1100.         pnum++;
  1101.     if (pnum >=NPORTS)
  1102.         return(-1);
  1103.     else
  1104.         return(pnum);
  1105. }
  1106.  
  1107. /**************************************************************************/
  1108. /*
  1109.  * netuclose( port)             - close the udp port 
  1110.  */
  1111.  
  1112. netuclose( port)
  1113. int port;
  1114. {
  1115.     UDPRPtr p;
  1116.     UDPiopb *pbp;
  1117.     int pnum;
  1118.     
  1119.     pnum= UDPfindport( port);
  1120.     
  1121.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  1122.         return(-1);
  1123.     
  1124.     p=uport[pnum];
  1125.     
  1126.     pbp = getUPB( TCPd, UDPRelease, p->stream, 0);
  1127.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1128.         putln("UDPClose failed"); return(-1);
  1129.         }
  1130.     DisposPtr( p->buffer);
  1131.     DisposPtr((Ptr) uport[pnum]);
  1132.     uport[pnum]=0;                /* use me again */
  1133.     
  1134.     returnPB( pbp);
  1135. }
  1136.  
  1137. /*************************************************************************/
  1138. /*  Mnetshut
  1139. *   Close all the connections and turn off the hardware.
  1140. */
  1141. Mnetshut()                                        /* BYU 2.4.16 */
  1142.     {
  1143.     int i;
  1144.  
  1145.     for (i=0; i < NPORTS ; i++) 
  1146.         if (streams[i] != (StreamRPtr) NULL)
  1147.             netabort(i);                        /* Prolly should abort */
  1148.     for (i=0; i < NPORTS ; i++) 
  1149.         if (uport[i] != (UDPRPtr) NULL)
  1150.             netuclose(uport[i]->port);            /* Shut down UDP too... */
  1151. #ifdef SAFE
  1152.     CloseDriver( TCPd);
  1153. #endif SAFE
  1154. }
  1155.  
  1156. /**************************************************************************/
  1157. int findbystream( streamPtr)
  1158. StreamPtr streamPtr;
  1159. {
  1160.     int pnum=0;
  1161.     
  1162.     while (pnum<NPORTS &&
  1163.             ( (streams[pnum] ==(StreamRPtr)0L) || (streamPtr !=streams[pnum]->stream)))
  1164.         pnum++;
  1165.     if (pnum >=NPORTS)
  1166.         return(-1);
  1167.     else
  1168.         return(pnum);
  1169. }
  1170.  
  1171.  
  1172. /**************************************************************************/
  1173. pascal void TCPNotify( streamPtr, code, uptr, terminReason, icmpMsg)
  1174. StreamPtr streamPtr;
  1175. unsigned short /*enum  TCPEventCode*/ code;
  1176. unsigned short /*enum  TCPTerminationReason*/ terminReason;
  1177. struct ICMPReport *icmpMsg;
  1178. Ptr uptr;   /* user data pointer */
  1179. {
  1180. #pragma unused(uptr, terminReason, icmpMsg)
  1181.     StreamRPtr p;
  1182.     int pnum;
  1183.     
  1184.     pnum = findbystream(streamPtr);
  1185.     
  1186.     if (pnum < 0 || (p = streams[pnum]) == 0L)
  1187.         return;
  1188.     
  1189.     switch( code) {
  1190.         case TCPTerminate:
  1191.         case TCPClosing:
  1192.             netputevent(CONCLASS, CONCLOSE, pnum);
  1193.             break;
  1194.         case TCPULPTimeout:
  1195.             netputevent(CONCLASS, CONFAIL, pnum);
  1196.             break;
  1197.         case TCPDataArrival:
  1198.         case TCPUrgent:
  1199.             netputuev(CONCLASS, CONDATA, pnum);
  1200.             break;
  1201.         case TCPICMPReceived:
  1202.         default:
  1203.             break;
  1204.         }
  1205.     return;
  1206. }
  1207.  
  1208. /*************************************************************************/
  1209. /*  Mnetopen2
  1210. *   Send out repeat SYN on a connection which is not open yet
  1211. *   Checks, and only sends one if needed.
  1212. *   Returns 1 if the state is still SYNS and 0 if the connection has proceeded.
  1213. *   The timing is all handled at a higher layer.
  1214. */
  1215. int Mnetopen2                                            /* BYU 2.4.16 */
  1216.   (
  1217.     int pnum
  1218.   )
  1219. {
  1220.     return( netest(pnum));
  1221. }
  1222.  
  1223. /**************************************************************************/
  1224. long openComplete( pbp)
  1225. TCPiopb *pbp;
  1226. {
  1227.     StreamRPtr p;
  1228.     int pnum;
  1229.     
  1230.     pnum= findbystream(pbp->tcpStream);
  1231.     
  1232.     if (pnum < 0 || (p = streams[pnum]) == 0L) 
  1233.         return(-1);
  1234.         
  1235.     if (pbp->ioResult !=noError) 
  1236.         netputevent(CONCLASS, CONFAIL, pnum);            /* Failure ... */
  1237.     else 
  1238.         netputevent(CONCLASS, CONOPEN, pnum);            /* Success ! */
  1239.  
  1240.     returnPB( pbp);
  1241.     return(0);
  1242. }
  1243.  
  1244. /**************************************************************************/
  1245. /*
  1246.  *    giveback( p, wds) -
  1247.  *        gives WDS entries back to the stream by putting them in the 
  1248.  *        mutually exclusive buffer.
  1249.  *    p -> stream
  1250.  *    wds -> wds array
  1251.  */
  1252. giveback( p, wds)
  1253. StreamRPtr p;
  1254. wdsEntry *wds;
  1255. {
  1256.     int n=0, m=0;
  1257.     
  1258.     while ( n< MAX_SWDS_ELEMS && wds[n].ptr !=0L) {
  1259.         while (m< MAX_FDS_ELEMS && p->exFDS[ m].inuse) m++;
  1260.         if (m> MAX_FDS_ELEMS)
  1261.             return(-1);                /* No room in the RECLAIMation center */
  1262.         else {
  1263.             p->exFDS[ m].inuse =1;
  1264.             p->exFDS[ m].fds = wds[n];
  1265.             m++;
  1266.             }
  1267.         n++;
  1268.         }
  1269. }
  1270.  
  1271.  
  1272. /**************************************************************************/
  1273. long sendComplete( pbp)
  1274. TCPiopb *pbp;
  1275. {
  1276.     StreamRPtr p;
  1277.     int pnum;
  1278.     wdsEntry *swds;
  1279.     int i=0,j=0;
  1280.     
  1281.     (Ptr) swds = pbp->csParam.send.wdsPtr;
  1282.     
  1283.     pnum= findbystream(pbp->tcpStream);
  1284.     if (pnum < 0 || (p = streams[pnum]) == 0L)
  1285.         return(-1);
  1286.  
  1287.     returnSWDS( swds);
  1288.     returnPB( pbp);
  1289.  
  1290.     giveback( p, pbp->csParam.send.wdsPtr);            /* Give this back.... NOW */
  1291.     
  1292.     return(0);
  1293. }
  1294.  
  1295.  
  1296. /**************************************************************************/
  1297. long closeComplete( pbp)
  1298. TCPiopb *pbp;
  1299. {
  1300.     StreamRPtr p;
  1301.     int pnum;
  1302.     
  1303.     pnum= findbystream(pbp->tcpStream);
  1304.     
  1305.     if (pnum < 0 || (p = streams[pnum]) == 0L)
  1306.       {
  1307.         netputevent(SCLASS, CLOSEDONE+1, pnum);
  1308.         return(-1);
  1309.       }
  1310.         
  1311.     if (pbp->ioResult !=noError) 
  1312.         netputevent(SCLASS, CLOSEDONE+1, pnum);
  1313.     else 
  1314.         netputevent(SCLASS, CLOSEDONE, pnum);            /* Success ! */
  1315.  
  1316.     returnPB( pbp);
  1317.     return(0);
  1318. }
  1319.  
  1320.  
  1321.  
  1322. /*****************************************************************************
  1323.  *
  1324.  * Here lie the awful UDP routines, I put them here for the drivers from Apple.
  1325.  *
  1326.  */
  1327.  
  1328.  int UDPlisten =0;                /* what port the old routines listen for */
  1329.  
  1330.  
  1331. /****************************************************************************/
  1332. /*                    New UDP routines....                                    */
  1333. /****************************************************************************/
  1334.  
  1335. /**************************************************************************/
  1336. makeuport( port)
  1337. int port;
  1338. {
  1339.     int    pnum;
  1340.     UDPRPtr p;
  1341.     UDPiopb *pbp;
  1342.     int i;
  1343.     
  1344.     for ( pnum=0; uport[pnum]!= NULL && pnum<NPORTS; pnum++);
  1345.     
  1346.     if (pnum >= NPORTS)
  1347.         return(-2);
  1348.  
  1349.     p = uport[pnum] = (UDPRPtr) NewPtr(sizeof(UDPRec));
  1350.  
  1351.     if ((p->buffer = (char *) NewPtr( UDPBUFSIZ)) == (char *)NULL)
  1352.         return(-1);
  1353.     
  1354.     
  1355.     pbp=getUPB( TCPd, UDPCreate, 0, pnum);            /* Make create call */
  1356.     
  1357.     pbp->csParam.create.rcvBuff  = p->buffer;
  1358.     pbp->csParam.create.rcvBuffLen= UDPBUFSIZ;
  1359.     pbp->csParam.create.notifyProc     = UDPNotify;
  1360.     pbp->csParam.create.localPort = port;
  1361.     
  1362.     if ((i=PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
  1363.         char temp[50];
  1364.         sprintf(temp, "UDPCreate failed (%d)",i);
  1365.         putln(temp);
  1366.         return(-1);
  1367.         }
  1368.     else {
  1369.         char temp[50];
  1370.         sprintf(temp, "UDPCreate successfull on %d(%d) [%x]",port,pnum,pbp->udpStream);
  1371.         putln(temp);
  1372.         }
  1373.     
  1374.     p->stream = pbp->udpStream;
  1375.     p->port = port;
  1376.     
  1377.     putln("Made a new UPORT");
  1378.     returnPB(pbp);
  1379.     return(pnum);
  1380. }
  1381.  
  1382. /**************************************************************************/
  1383. /*
  1384.  * netuopen (port)             - open the udp port "Port"
  1385.  */
  1386.  
  1387. netuopen(port)
  1388. int port;
  1389. {
  1390.     return(makeuport( port));
  1391. }
  1392.  
  1393. /**************************************************************************/
  1394. /*
  1395.  *    netuget( port, buffer,len, who,where)
  1396.  *                    - read up to len bytes from port port into buffer buffer, noting
  1397.  *                        who it was from and where....
  1398.  */
  1399.  
  1400. netuget( port, buffer, len, who, where)
  1401. int port, len;
  1402. int *who, *where;
  1403. char *buffer;
  1404. {
  1405. #pragma unused(who, where)
  1406.     int pnum, length;
  1407.     UDPRPtr p;
  1408.     UDPiopb *pbp;
  1409.     
  1410.     pnum= UDPfindport( port);
  1411.     
  1412.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  1413.         return(-1);
  1414.     
  1415.     p=uport[pnum];
  1416.     
  1417.     pbp= getUPB( TCPd, UDPRead, p->stream, 0);
  1418.     pbp->csParam.receive.timeOut = 1;                            /* time out at one sec. */
  1419.     
  1420.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1421.         putln("UDPRead failed"); return(-1);
  1422.         }
  1423.     
  1424.     length = pbp->csParam.receive.rcvBuffLen;                /* look how BIG it is */
  1425.     length = length > len ? len:length;
  1426.     
  1427.     memcpy( buffer, pbp->csParam.receive.rcvBuff,length);
  1428.     
  1429.     pbp->csCode = UDPBfrReturn;                                /* Let my buffer go.. */
  1430.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1431.         putln("UDPReturn failed"); return(-1);
  1432.         }
  1433.         
  1434.     returnPB( pbp);
  1435.     
  1436.     return(length);
  1437. }
  1438.  
  1439. /**************************************************************************/
  1440. netuput( machine, port, myport, buffer, n)
  1441. long *machine;
  1442. char *buffer;
  1443. int port, myport;
  1444. int n;
  1445. {
  1446.     wdsEntry wds[2];
  1447.     UDPRPtr p;
  1448.     UDPiopb *pbp; int pnum;
  1449.     
  1450.     pnum= UDPfindport( myport);
  1451.     
  1452.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  1453.         return(-1);
  1454.     
  1455.     p=uport[pnum];
  1456.     
  1457.     pbp= getUPB( TCPd, UDPWrite, p->stream, 0);
  1458.     pbp->csParam.send.remoteHost = *machine;
  1459.     pbp->csParam.send.remotePort = port;
  1460.     pbp->csParam.send.checkSum   = 1;                    /* Do do that checksum that you do so well */
  1461.     pbp->csParam.send.wdsPtr = (Ptr) wds;
  1462. /*    pbp->csParam.send.remoteHost = *machine;    /* BYU - not needed, done above. */
  1463.     
  1464.     wds[0].ptr = buffer;
  1465.     wds[0].length=n;
  1466.     wds[1].ptr = (char *) 0L; wds[1].length=0;
  1467.     
  1468.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1469.         putln("UDPReturn failed"); return(-1);
  1470.         }
  1471.         
  1472.     returnPB( pbp);
  1473.     return(0);
  1474. }
  1475.  
  1476.  
  1477. /****************************************************************************/
  1478. /*  Mneturead
  1479. *   get the data from the UDP buffer
  1480. *   Returns the number of bytes transferred into your buffer, -1 if none here
  1481. *   This needs work.
  1482. */
  1483. int Mneturead                                    /* BYU 2.4.16 */
  1484.   (
  1485.     char *buffer
  1486.   )
  1487. {
  1488.     int who, where;
  1489.     
  1490.     if (!UDPlisten)
  1491.         return(-1);
  1492.         
  1493.     return( netuget( UDPlisten, buffer, 512, &who, &where));
  1494. }
  1495.  
  1496. /***************************************************************************/
  1497. /*  Mnetulisten
  1498. *   Specify which UDP port number to listen to.
  1499. *   Can only listen to one at a time.
  1500. */
  1501. int Mnetulisten                                    /* BYU 2.4.16 */
  1502.   (
  1503.     int port
  1504.   )
  1505. {
  1506.     char temp[50];
  1507.     int pnum;
  1508.  
  1509.     
  1510.     sprintf( temp, "UDP listening on ....%d", port);
  1511.     putln(temp);
  1512.     
  1513.     UDPlisten = port;
  1514.     
  1515.     if ( (pnum=UDPfindport( port))<0)
  1516.         pnum= netuopen(port);
  1517.     
  1518.     return (pnum);
  1519. }
  1520.  
  1521. /***************************************************************************/
  1522. /*  Mnetusend
  1523. *   send some data out in a UDP packet
  1524. *   uses the preinitialized data in the port packet ulist.udpout
  1525. *   
  1526. *   returns 0 on okay send, nonzero on error
  1527. */
  1528. void Mnetusend                                    /* BYU 2.4.16 */
  1529.   (
  1530.     unsigned char *machine,
  1531.     unsigned int port,
  1532.     unsigned int retport,
  1533.     unsigned char *buffer,
  1534.     int n
  1535.   )
  1536. {
  1537.     /* find if port is open */
  1538.     if ( UDPfindport( retport)<0)
  1539.         netuopen(retport);
  1540.     
  1541.     /* Send data */
  1542.     netuput( machine, port, retport, buffer,n);
  1543. }
  1544.  
  1545. /**************************************************************************/
  1546. int ufindbystream( streamPtr)
  1547. StreamPtr streamPtr;
  1548. {
  1549.     int pnum=0;
  1550.     
  1551.     while (pnum<NPORTS &&
  1552.             ( uport[pnum] ==(UDPRPtr)0L || streamPtr !=uport[pnum]->stream))
  1553.         pnum++;
  1554.     if (pnum >=NPORTS)
  1555.         return(-1);
  1556.     else
  1557.         return(pnum);
  1558. }
  1559.  
  1560. /**************************************************************************/
  1561. pascal void UDPNotify( streamPtr, code, uptr, icmpMsg)
  1562. StreamPtr streamPtr;
  1563. unsigned short code;
  1564. struct ICMPReport *icmpMsg;
  1565. Ptr uptr;   /* user data */
  1566. {
  1567. #pragma unused(uptr, icmpMsg)
  1568.     UDPRPtr p;
  1569.     int pnum;
  1570.     
  1571.     pnum= ufindbystream(streamPtr);
  1572.     
  1573.     if (pnum < 0 || (p = uport[pnum]) == 0L)
  1574.         return;
  1575.     
  1576.     switch( code) {
  1577.         case UDPDataArrival:
  1578.             netputuev(USERCLASS,UDPDATA,p->port);        /* post that it is here */
  1579.         default:
  1580.             break;
  1581.         }
  1582.     return;
  1583. }
  1584.  
  1585. #if 0                                                    /* BYU 2.4.16 */
  1586. void netconfig
  1587.   (
  1588.     char *hardware
  1589.   )
  1590. {
  1591. #pragma unused(hardware)
  1592.     putln("I'm a driver TCP, I don't need hardware.....");
  1593.     initipnum(0);
  1594. }
  1595.  
  1596. void netarpme
  1597.   (
  1598.     char *s
  1599.   )
  1600. {
  1601. #pragma unused(s)
  1602.     putln("Drivers don't need arps, either.");
  1603. }
  1604.  
  1605. netsetgate(s)
  1606. char *s;
  1607. {
  1608. #pragma unused(s)
  1609.     putln("Yeah, right....");
  1610.     return
  1611.         0;
  1612. }
  1613.  
  1614. int netgetrarp
  1615.   (
  1616.     void
  1617.   )
  1618. {
  1619.     putln("RARP handled above me....");
  1620.     return
  1621.         0;
  1622. }
  1623.  
  1624. uint8 *getdlayer()
  1625. {
  1626.     putln("This shouldn't be called...");
  1627.     return(0L);
  1628. }
  1629.  
  1630. tcpsend()
  1631. {
  1632. }
  1633.  
  1634. demux()
  1635. {
  1636.     return(0);
  1637. }
  1638.  
  1639. /*************************************************************************/
  1640. /* neteventinit
  1641. *  load up the pointers for the event queue
  1642. *  makes a circular list to follow, required for error messages
  1643. */
  1644. void neteventinit
  1645.   (
  1646.     void
  1647.   )
  1648.     {
  1649.     int i;
  1650.  
  1651.     for (i=0; i < NEVENTS; i++)
  1652.         nnq[i].next = i+1;
  1653.  
  1654.     nnq[NEVENTS-1].next = -1;
  1655.  
  1656.     nnefirst = 0;
  1657.     nnelast = 0;
  1658.     nnefree = 1;
  1659. }
  1660.  
  1661. getATaddress()
  1662. {
  1663. }
  1664.  
  1665. KIPfindgate()
  1666. {
  1667. }
  1668.  
  1669. KIPgetns()
  1670. {
  1671. }
  1672.  
  1673. KIPgetdynam()
  1674. {
  1675. }
  1676.  
  1677. KIPregister()
  1678. {
  1679. }
  1680. #endif                                                    /* BYU 2.4.16 */